﻿/*
    This file is part of File Renamer.

    File Renamer is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 3.

    File Renamer is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace FileRenamer
{
    enum PREFIX_SUFIX_TYPE
    {
        ASC,
        DES,
        RND
    }

    struct ChangedFileName
    {
        public String prefix;
        public String sufix;

        public String nameBase;
        public String ext;
        public bool assigned;
    }

    class FileMaster
    {
        private FileInfo[] loadedFiles;
        private ChangedFileName[] ChangedNames;
        private Random objRnd = new System.Random();


        public FileMaster()
        {
        }

        private void CopyFileNamesIntoChangedFileName()
        {
            List<ChangedFileName> fileNameBuffer = new List<ChangedFileName>();

            for (int i = 0; i < loadedFiles.Length; i++)
            {
                String fName = loadedFiles[i].Name;
                if (loadedFiles[i].Extension.Length > 0)
                {
                    fName = fName.Remove(fName.Length - loadedFiles[i].Extension.Length);
                }
                ChangedFileName cFile = new ChangedFileName();
                cFile.nameBase = fName;
                cFile.ext = loadedFiles[i].Extension;

                fileNameBuffer.Add(cFile);
            }

            ChangedNames = fileNameBuffer.ToArray();
        }

        public void UpadateFiles(FileInfo[] loadedFiles)
        {
            this.loadedFiles = loadedFiles;
            CopyFileNamesIntoChangedFileName();
        }

        private String PushStringFromRightToLeftIntoPaddingString(String stringToPush, String paddingString)
        {
            if (stringToPush.Length >= paddingString.Length)
                return stringToPush;
            
            int insertAt = paddingString.Length - stringToPush.Length;
            String newString = paddingString.Insert(insertAt, stringToPush);
            newString = newString.Remove(paddingString.Length);

            return newString;
        }

        public void AddNumericSufix(int startFrom, int step, PREFIX_SUFIX_TYPE sufixType, String paddingMask)
        {
            int x;  // needed outside of for loop that locates random unassigned file

            switch (sufixType)
            {
                case PREFIX_SUFIX_TYPE.ASC:
                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i += step, m++)
                    {
                        ChangedNames[m].sufix = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                    }
                    break;

                case PREFIX_SUFIX_TYPE.DES:
                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i -= step, m++)
                    {
                        ChangedNames[m].sufix = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                    }
                    break;

                case PREFIX_SUFIX_TYPE.RND:

                    // initialize the assigned flags in ChangedNames
                    for (int j = 0; j < loadedFiles.Length; j++)
                        ChangedNames[j].assigned = false;

                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i += step, m++)
                    {
                        for (x = objRnd.Next(0, loadedFiles.Length); ChangedNames[x].assigned; x = objRnd.Next(0, loadedFiles.Length))
                        { }  //Loop until a random unassigned index is found
                        ChangedNames[x].sufix = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                        ChangedNames[x].assigned = true;
                    }
                    break;

            }
        }

        public void AddAlphabeticSufix()
        {
        }

        public void AddNumericPrefix(int startFrom, int step, PREFIX_SUFIX_TYPE prefixType, String paddingMask)
        {

            int x;  // needed outside of for loop that locates random unassigned file

            switch(prefixType)
            {
                case PREFIX_SUFIX_TYPE.ASC:
                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i+=step, m++)
                    {
                        ChangedNames[m].prefix = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                    }
                    break;

                case PREFIX_SUFIX_TYPE.DES:
                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i-=step, m++)
                    {
                        ChangedNames[m].prefix = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                    }
                    break;

                case PREFIX_SUFIX_TYPE.RND:
                   // initialize the assigned flags in ChangedNames
                    for (int j = 0; j < loadedFiles.Length;j++)
                        ChangedNames[j].assigned = false;

                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i += step, m++)
                    {
                        for (x = objRnd.Next(0, loadedFiles.Length); ChangedNames[x].assigned; x = objRnd.Next(0, loadedFiles.Length)) 
                        { }  //Loop until a random unassigned index is found
                        ChangedNames[x].prefix = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                        ChangedNames[x].assigned = true;
                    }
                    break;
            }

        }


        public void AddAlphabeticPrefix()
        {
        }


        public void AddStaticPrefix(String prefix)
        {
            for (int i = 0; i < ChangedNames.Length; i++)
            {
                ChangedNames[i].prefix = prefix;
            }
        }

        public void AddStaticSufix(String sufix)
        {
            for (int i = 0; i < ChangedNames.Length; i++)
            {
                ChangedNames[i].sufix = sufix;
            }
        }

        public void ResetPrefix()
        {
        }

        public void ResetSufix()
        {
        }

        public bool CheckFileNames()
        {
            for (int i = 0; i < ChangedNames.Length; i++)
            {
                String fileName = ChangedNames[i].prefix + ChangedNames[i].nameBase +
                                  ChangedNames[i].sufix + ChangedNames[i].ext;

                String extension = ChangedNames[i].ext;

                String path = loadedFiles[i].DirectoryName;

                String fullNewName = path + "\\" + fileName;

                if (File.Exists(fullNewName))
                {
                    return false;
                }
            }
            return true;
        }


        public void Rename()
        {
            for (int i = 0; i < ChangedNames.Length; i++)
            {
                String fileName = ChangedNames[i].prefix + ChangedNames[i].nameBase +
                                  ChangedNames[i].sufix + ChangedNames[i].ext;

                String extension = ChangedNames[i].ext;

                String path = loadedFiles[i].DirectoryName;

                String fullNewName = path + "\\" + fileName;

                String oldName = loadedFiles[i].FullName;

                File.Move(oldName, fullNewName);
            }
        }

        public void ModifyNames_Static(String name)
        {
            for (int i = 0; i < ChangedNames.Length; i++)
            {
                ChangedNames[i].nameBase = name;
            }
        }

        public void ModifyNames_Alphabetic(String startFrom, PREFIX_SUFIX_TYPE type, String paddingMask)
        {
        }

        public void ModifyNames_Numeric(int startFrom, int step, PREFIX_SUFIX_TYPE nameBaseType, String paddingMask)
        {
            int x;  // needed outside of for loop that locates random unassigned file

            switch (nameBaseType)
            {
                case PREFIX_SUFIX_TYPE.ASC:
                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i += step, m++)
                    {
                        ChangedNames[m].nameBase = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                    }
                    break;

                case PREFIX_SUFIX_TYPE.DES:
                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i -= step, m++)
                    {
                        ChangedNames[m].nameBase = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                    }
                    break;

                case PREFIX_SUFIX_TYPE.RND:
                    // initialize the assigned flags in ChangedNames
                    for (int j = 0; j < loadedFiles.Length; j++)
                        ChangedNames[j].assigned = false;

                    for (int i = startFrom, m = 0; m < loadedFiles.Length; i += step, m++)
                    {
                        for (x = objRnd.Next(0, loadedFiles.Length); ChangedNames[x].assigned; x = objRnd.Next(0, loadedFiles.Length))
                        { }  //Loop until a random unassigned index is found
                        ChangedNames[x].nameBase = PushStringFromRightToLeftIntoPaddingString(i.ToString(), paddingMask);
                        ChangedNames[x].assigned = true;
                    }
                    break;
            }
        }

        public void InsertTextInFileName(int position, String text)
        {
            for (int m = 0; m < loadedFiles.Length; m++)
            {
                String fileName = ChangedNames[m].nameBase;

                if (position > fileName.Length)
                {
                    fileName = fileName.Insert(fileName.Length, text);
                }
                else
                {
                    fileName = fileName.Insert(position, text);
                }

                ChangedNames[m].nameBase = fileName;
            }
        }

        public void DeleteSybmols(int position, int symbolsNumber)
        {
            for (int m = 0; m < loadedFiles.Length; m++)
            {
                String fileName = ChangedNames[m].nameBase;

                if (position > fileName.Length)
                {
                    continue;
                }
                else if (fileName.Length - position < symbolsNumber)
                {
                    fileName = fileName.Remove(position);
                }
                else
                {
                    fileName = fileName.Remove(position, symbolsNumber);
                }

                ChangedNames[m].nameBase = fileName;
            }
        }

        public String[] GetChangedFileNamesForPreview()
        {
            List<String> fileNames = new List<string>();

            for (int i = 0; i < ChangedNames.Length; i++)
            {
                String fileName;

                fileName = ChangedNames[i].prefix + ChangedNames[i].nameBase +
                    ChangedNames[i].sufix + ChangedNames[i].ext;

                fileNames.Add(fileName);
            }

            return fileNames.ToArray();
        }

    }
}
